/**
 * 规格组件
 */
layui.define(['component', 'layer', 'util', 'form', 'table', 'methods', 'upload','tabs'], function (exports) {
    var methods = layui.methods,
        o = layui.jquery,
        form = layui.form,
        table = layui.table,
        upload = layui.upload,
        ly = layui.layer,
        tabs = layui.tabs,
        data = {},
        tape = [],
        options = {},
        currentSpec = [];

    const getOptions = async (url) => {
        const d = await methods.fetchGetPromise(url, {id: o(`input[name="id"]`).val()}, false);
        if (d.code !== 1) {
            ly.msg('加载失败');
            return false;
        }
        data = d.data;
    }

    const build = {
        load: () => {
            options.elem.html(`
            <div style="padding: 0 20px">
                <i class="layui-icon layui-icon-loading-1 layui-anim layui-anim-rotate layui-anim-loop"></i> 
                <span style="font-size: 13px;color: #515a6e;margin-left: 5px">加载中...</span>
            </div>
            `)
        },
        css: () => {
            layui.link('/static/admin/addons/builderPlus/css/spec.css');
        },
        takeTape: () => {
            var fVal = form.val('form');
            data.type.map((v) => {
                if (v.id === parseInt(fVal.type_id)) tape = v.tape;
            })
        },
        specType: () => {
            computed = (val) => {
                return !data.info && val === 1
                    ? 'checked'
                    : (data.info && parseInt(data.info.spec_open) === val ? 'checked' : '');
            }
            /*return [
                '<div class="layui-col-xs12 layui-col-sm12 layui-col-md12">',
                '<div class="layui-form-item">',
                '<label class="layui-form-label">商品规格</label>',
                '<div class="layui-input-block">',
                '<input type="radio" name="spec_open" ' + computed(1) + ' value="1" title="单规格" lay-filter="specOpen">',
                '<input type="radio" name="spec_open"  ' + computed(2) + ' value="2" title="多规格" lay-filter="specOpen">',
                '</div>',
                '</div>',
            ].join('');*/
            return '';
        },
        single: (reload = false) => {
            const load = () => {
                computed = (item) => {
                    var val = data.info ? data.info[item.field] : '';
                    return [
                        '<div class="layui-col-xs12 layui-col-sm12 layui-col-md12">',
                        '<div class="layui-form-item">',
                        '<label class="layui-form-label">' + item.title + '</label>',
                        '<div class="layui-input-block">',
                        '<input type="number" name="' + item.field + '" value="' + val + '" placeholder="请填写' + item.title + '" autocomplete="off" class="layui-input" style="width: 190px">',
                        '</div>',
                        '</div>',
                        '</div>',
                    ].join('');
                }
                var hide = !data.info || data.info.spec_open === 1 ? '' : 'style="display: none;"';
                var html = reload ? '' : '<div class="single" ' + hide + '>';
                tape.map((v) => {
                    if (v.type !== 'icon') html += computed(v)
                });
                return html + (reload ? '' : '</div>');
            }
            if (reload) {
                return load();
            } else if (!o('.single').length) {
                return load();
            } else {
                return '';
            }

        },
        multiple: (reload = false) => {

            const load = () => {
                var hide = !data.info || data.info.spec_open === 1 ? 'style="display: none;"' : '';
                var html = reload ? '' : '<div class="multiple" ' + hide + '>';
                html += build.chooseSpec();

                html += build.operateSpec();

                html += build.table();

                return html + (reload ? '' : '</div>');
            }

            if (reload) {
                return load();
            } else if (!o('.multiple').length) {
                return load();
            } else {
                return '';
            }

        },
        table: () => {
            return [
                '<div class="layui-col-xs12 layui-col-sm12 layui-col-md12">',
                '<div class="layui-form-item spec-table">',
                '<label class="layui-form-label">商品属性</label>',
                '<div class="layui-input-block">',
                '<div class="spec-table table">',
                '<table class="layui-hide" id="specTable" lay-filter="specTable"></table>',
                '</div>',
                '</div>',
                '</div>',
                '</div>',
            ].join('');
        },
        operateSpec: () => {
            return [
                '<div class="layui-col-xs12 layui-col-sm12 layui-col-md12">',
                '<div class="layui-form-item">',
                '<label class="layui-form-label"></label>',
                '<div class="layui-input-block">',
                '<div class="spec-box"></div>',
                '<div class="add-spec" style="margin-top:10px">',
                '<div class="layui-inline add-spec-item hide">',
                '<label class="layui-form-label w80">规格：</label>',
                '<div class="layui-input-inline">',
                '<input type="text" id="spec-title" placeholder="请填写规格" autocomplete="off" class="layui-input">',
                '</div>',
                '</div>',
                '<div class="layui-inline add-spec-item hide">',
                '<label class="layui-form-label w80">规格值：</label>',
                '<div class="layui-input-inline">',
                '<input type="text" id="spec-val" placeholder="请填写规格值" autocomplete="off" class="layui-input">',
                '</div>',
                '</div>',
                '<div class="layui-inline add-btn-box">',
                '<a class="layui-btn layui-btn-normal layui-btn-sm add-spec-btn" lay-click="addSpecItem">添加新规格</a>',
                '<a class="layui-btn layui-btn-sm add-spec-item hide" lay-click="addSpecItemConfirm">确定</a>',
                '<a class="layui-btn layui-btn-sm layui-btn-primary add-spec-item hide" lay-click="addSpecItemClear">取消</a>',
                '</div>',
                '</div>',
                '</div>',
                '</div>',
                '</div>',
            ].join('');
        },
        chooseSpec: () => {
            computed = () => {
                var html = '<option value="">请选择</option>';
                data.specTpl.map((v) => {
                    html += '<option value="' + v.id + '">' + v.title + '</option>'
                });
                return html;
            }
            return [
                '<div class="layui-col-xs12 layui-col-sm12 layui-col-md12">',
                '<div class="layui-form-item">',
                '<label class="layui-form-label">选择规格</label>',
                '<div class="layui-input-inline">',
                '<select name="spec_id" lay-search lay-filter="chooseSpec" id="spec_id">',
                computed(),
                '</select>',
                '</div>',
                '</div>',
                '</div>',
            ].join('');
        },
        specBox: (data, specBox) => {
            computedChild = (child, pid) => {
                var html = '';
                child.map((item) => {
                    html += [
                        '<div class="spec-item-child">',
                        '<span>' + item.title + '</span>',
                        '<i class="layui-icon layui-icon-close" data-id="' + item.id + '" data-pid="' + pid + '" lay-click="clearSpecItemChild"></i>',
                        '</div>',
                    ].join('');
                });
                return html;
            }
            computed = (item, index) => {
                return [
                    '<div class="spec-item" data-index="' + index + '">',
                    '<div class="spec-item-sortable" style="padding-left: 0">',
                    '<div class="spec-item-child-title">',
                    '<span>' + item.title + '</span>',
                    '<i class="layui-icon layui-icon-close " data-index="' + index + '" lay-click="clearSpecItem"></i>',
                    '</div>',
                    '<div class="spec-content">',
                    '<div class="spec-item-child-lay" style="align-items: center">',
                    computedChild(item.child, item.id),
                    '<div class="layui-form-item" style="margin-bottom: 0 !important;">',
                    '<div class="layui-input-inline layui-input-wrap">',
                    '<input type="text" autocomplete="off"  class="layui-input attribute" data-id="' + item.id + '" placeholder="填写规格值">',
                    '</div>',
                    '<div class="layui-form-mid " data-id="' + item.id + '" lay-click="addSpecItemChild">',
                    '<button type="button" class="layui-btn layui-btn-sm">添加</button>',
                    '</div>',
                    '</div>',
                    '</div>',
                    '</div>',
                    '</div>',
                    '</div>'
                ].join('');
            }
            var html = '';

            data.map((item, index) => {
                html += computed(item, index);
            });
            currentSpec = data;
            specBox.html(html);
        },
        cartesianProduct: (arrays) => {
            return arrays.reduce((acc, arr) =>
                acc.flatMap(comb =>
                    arr.map(item => [...comb, item])
                ), [[]]
            );
        },
        generateCombinations: (specs, fast = false) => {
            // 提取所有规格选项
            const allOptions = specs.map(spec => spec.child);
            // 计算笛卡尔积
            const combinations = build.cartesianProduct(allOptions);

            const tableData = table.getData('specTable');

            return combinations.map(combination => {
                const merge_id = combination.map(item => item.id).join(',');
                const merge_title = combination.map(item => item.title).join(',');
                const title = combination.map(item => item.title).join(' - ');
                let current = {};

                tableData.map((v) => {
                    if (v.merge_id === merge_id) {
                        current = v;
                    }
                })
                // 构建组合对象（动态包含所有规格字段）
                const comboObj = {
                    merge_id: merge_id,
                    merge_title: merge_title,
                    title: title
                };

                //附加自定义字段
                tape.forEach((item) => {
                    comboObj[item.field] = '';
                })

                // 为每个规格添加独立字段
                if (options.alone) {
                    specs.forEach((spec, index) => {
                        comboObj[spec.title] = combination[index].title;
                    });
                }
                if (fast) {

                    data.info.productSpec.map((v) => {
                        if (v.merge_title === merge_title) {
                            tape.forEach((item) => {
                                comboObj[item.field] = v[item.field];
                            })
                        }
                    })


                } else {
                    tape.forEach((item, index) => {
                        comboObj[item.field] = current[item.field] ? current[item.field] : '';
                    })
                }


                return comboObj;
            });
        },
        generateColumns: (specs) => {
            // 固定列：组合ID和组合规格
            const baseColumns = [
                {field: 'merge_id', title: '组合ID', hide: true},
                {field: 'merge_title', title: '组合规格', hide: true},
                {field: 'title', title: '规格', minWidth: 200},
            ];

            // 动态列：独立字段
            if (options.alone) {
                specs.forEach(spec => {
                    baseColumns.push({
                        field: spec.title,
                        title: spec.title,
                        align: 'center'
                    });
                });
            }


            const takeIcon = (item) => {
                return `<div style="cursor: pointer" class="upload-icon"> 
                    {{# if(d.${item.field}){ }}
                    <img src="{{d.${item.field}}}" class="spec-icon"/>
                    {{# }else{ }}
                    <i class="layui-icon layui-icon-picture spec-i"></i>
                    {{# } }}
                    </div>`
            }

            const takeInput = (item) => {
                return `<div> 
                            <input type="number" placeholder="请填写" autocomplete="off" class="layui-input ${item.field}" value="{{d.${item.field}}}" style="text-align: center" >
                        </div>
                        `
            }

            // 动态列：动态价格等
            tape.forEach((item, index) => {

                const title = item.type === 'icon'
                    ? '<i data-batch="1" class="layui-icon layui-icon-picture upload-icon" style="font-weight: 300;font-size: 14px;cursor: pointer;margin-left: 5px"></i>'
                    : '<i lay-click="batch" class="layui-icon layui-icon-cols" style="font-weight: 300;font-size: 14px;cursor: pointer;margin-left: 5px"></i>';

                baseColumns.push({
                    field: item.field,
                    title: `${item.title}` + title,
                    width: item.type === 'icon' ? 90 : 150,
                    align: 'center',
                    templet: item.type === 'icon' ? takeIcon(item) : takeInput(item),
                });
            })

            return baseColumns;
        },
        uploads: () => {
            upload.render({
                elem: '.upload-icon',
                url: options.uploads,
                multiple: true,
                data: {
                    type: 1,
                },
                before: function (obj) {
                    ly.msg('上传中', {
                        shade: 0.4,
                        time: 0
                    });
                },
                done: function (data, index, upload) {
                    ly.closeAll();
                    var that = this.elem,
                        parents = that.parents('tr'),
                        table_id = that.parents('.layui-table-view').attr('lay-table-id');

                    if(that.attr('data-batch')){
                        let tableData = table.getData('specTable');
                        tableData.forEach((v) => {
                            v.icon = data.data.url;
                        })
                        table.reloadData('specTable', {
                            data: tableData
                        });
                    }else{
                        var thisCache = table.cache[table_id] || {};
                        that.html(data.data.url ? '<img src="' + data.data.url + '" class="spec-icon"/>' : '<i class="layui-icon layui-icon-picture spec-i"></i>');
                        thisCache[parents.attr('data-index')].icon = data.data.url;
                    }

                },
                error: function () {
                    ly.closeAll();
                    ly.msg('上传失败');
                }
            });
        },
        renderSpecTable: (fast = false) => {
            const comboCols = build.generateColumns(currentSpec);
            const comboData = build.generateCombinations(currentSpec, fast);

            table.render({
                elem: '#specTable',
                data: comboData,
                cols: [comboCols],
                page: false,
                size: 'sm',
                done: function () {
                    var that = this;
                    table.getRowData = function (elem) {
                        var index = o(elem).closest('tr').data('index');
                        return table.cache[that.id][index] || {};
                    };
                    tape.map((v) => {
                        o(options.elem).on('input', `.${v.field}`, function (e) {
                            var data = table.getRowData(o(this)), val = o(this).val();
                            if (val <= 0) {
                                data[v.field] = '';
                                o(this).val('');
                            } else {
                                data[v.field] = val;
                            }
                        })
                    })

                    build.uploads();
                }
            });
        },
    }

    const listener = (options) => {

        tabs.on('afterChange(productTabs)', function(data) {
            if(data.index === 1){
                table.resize('specTable');
            }
        });

        form.on('radio(specOpen)', function (data) {
            if (data.value === '1') {
                o('.single').show();
                o('.multiple').hide();
            } else {
                o('.single').hide();
                o('.multiple').show();
            }
        });


        form.on('select(type_id)', function (e) {
            data.type.map((v) => {
                if (v.id === parseInt(e.value)) {
                    tape = v.tape;

                    //重新渲染单规格
                    o('.single').html(build.single(true));

                    //重新渲染多规格
                    o('.multiple').html(build.multiple(true))

                    //渲染表单
                    form.render();
                }
            })

            if(e.value === '5'){
                o(".show-platoon-id").show();
            }else{
                o(".show-platoon-id").hide();
            }
        })

        form.on('select(chooseSpec)', function (res) {
            var specBox = o('.spec-box');
            if (!res.value) {
                specBox.html('');
                currentSpec = [];
                o(`div[lay-table-id="specTable"]`).remove();
                table.reloadData('specTable', {
                    data: []
                });
                return false;
            }
            methods.fetchGet(options.getSpec, {id: res.value}, function (d) {
                if (d.code === 1) {
                    build.specBox(d.data.specText, specBox);

                    build.renderSpecTable(!!data.info);
                } else {
                    ly.msg(d.msg);
                }
            }, false)
        });

        methods.event.click(['clearSpecItem', 'clearSpecItemChild', 'addSpecItemChild', 'addSpecItem', 'addSpecItemClear', 'addSpecItemConfirm', 'batch'], (data, that) => {
            if (currentSpec.length <= 1) {
                ly.msg('至少保留一个规格');
                return false;
            }
            currentSpec.splice(data.index, 1);
            o(`.spec-item[data-index=${data.index}]`).remove()

            build.renderSpecTable();
        }, (data, that) => {
            let open = true;
            currentSpec.forEach((v) => {
                if (v.id === data.pid) {
                    if (v.child.length <= 1) {
                        ly.msg('至少保留一个规格值');
                        open = false;
                    } else {
                        v.child.forEach((child, i) => {
                            if (data.id === child.id) v.child.splice(i, 1);
                        })
                    }
                }
            })
            if (open) {
                o(that).parents('.spec-item-child').remove()
                build.renderSpecTable();
            }

        }, (data, that) => {
            const val = o(`.attribute[data-id=${data.id}]`).val();
            let open = true;
            if (val) {
                currentSpec.forEach((v) => {
                    if (v.id === data.id) {
                        v.child.map((child) => {
                            if (child.title === val) {
                                ly.msg('该属性已存在');
                                open = false;
                                return false;
                            }
                        })
                        if (open) {
                            v.child.push({
                                id: (new Date().getTime()).toString(),
                                title: val
                            })
                        }
                    }
                });
            }
            if (open) {
                build.specBox(currentSpec, o('.spec-box'));
                build.renderSpecTable();
            }

        }, () => {
            o('.add-spec-item').show();
            o('.add-spec-btn').hide();
        }, () => {
            o('.add-spec-item').hide()
            o('.add-spec-btn').show();
        }, () => {
            const title = o('#spec-title').val(), val = o('#spec-val').val();
            let open = true;
            if (!title || !val) {
                ly.msg('请填写规格名称和规格值');
                return false;
            }
            currentSpec.map((v) => {
                if (v.title === title) {
                    ly.msg('规格已存在！');
                    open = false;
                    return false;
                }
            });
            if (open) {
                currentSpec.push({
                    id: (new Date().getTime()).toString(),
                    title: title,
                    child: [
                        {
                            id: (new Date().getTime()).toString(),
                            title: val
                        }
                    ]
                })

                build.specBox(currentSpec, o('.spec-box'));
                o('#spec-title').val('');
                o('#spec-val').val('');
                o('.add-spec-item').hide()
                o('.add-spec-btn').show();
                build.renderSpecTable();
            }
        }, (data, that) => {
            const th = o(that).parents('th'), field = th.attr('data-field'), title = th.attr('title');
            ly.prompt({title: `批量设置${title}`, formType: 0, placeholder: `请填写${title}`}, function (value, index) {
                if (!o.isNumeric(value) || value < 0) {
                    ly.msg('填写错误');
                    return false;
                }
                let tableData = table.getData('specTable');
                tableData.forEach((v) => {
                    v[field] = value;
                })
                table.reloadData('specTable', {
                    data: tableData
                });
                ly.close(index);
            });
        });

    }

    var component = layui.component({
        name: 'spec',
        config: {
            elem: '.layui-spec',
        },
        render: function () {
            var that = this, html = '';
            options = that.config;
            //友好加载框
            build.load();
            //加载css
            build.css();

            //获取规格等数据
            getOptions(options.getSpecOptions).then(() => {

                //提取相关价格
                build.takeTape();

                //渲染规格类别
                html += build.specType();

                //渲染单规格
                html += build.single();

                //渲染多规格
                html += build.multiple();

                //构建HTML
                options.elem.html(html);

                //渲染表单
                form.render();

                //开启监听
                listener(options);

                //渲染回显数据
                if (data.info && data.info.spec) {
                    build.specBox(JSON.parse(data.info.spec), o('.spec-box'));
                    build.renderSpecTable(true);
                }

            });
        },
    });

    layui.$.extend(component, {

        fun: {
            //获取规格数据
            getSpecData: () => {
                return table.getData('specTable');
            },
            //获取规格项
            getSpec: () => {
                return currentSpec;
            },
        }


    });

    exports(component.CONST.MOD_NAME, component);
});
